﻿using DocBot.Objects;
using DocBot.Util;
using DocBot.Util.Collections;

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows.Input;
using System.Xml.Serialization;

namespace DocBot.ViewModel
{
	public class BlacklistViewModel : ViewModelBase
	{
		#region Members
		private static string configFileName = "BlackList.xml";
		private LocalDataBase _database = new LocalDataBase();
		ThreadSafeObservableCollection<BlackListItem> _items = new ThreadSafeObservableCollection<BlackListItem>();
		int _selectedItem = -1;
		#endregion

		#region Properties
		public ThreadSafeObservableCollection<BlackListItem> Items
		{
			get
			{
				return _items;
			}
			set
			{
				_items = value;
			}
		}
		#endregion

		#region Construction
		public BlacklistViewModel()
		{
			if (IsInDesignMode)
			{
				LoadBlacklist(configFileName);
				if (_items.Count == 0)
					for (int i = 0; i < 50; ++i)
					{
						_items.Add(new BlackListItem { Object = _database.GetRandomArtistName, Added = DateTime.Now, Type = BlackListItemType.PlaylistItem });
					}
			}
			else
			{
				LoadBlacklist(configFileName);
			}
		}

		public int SelectedItem
		{
			get
			{
				return this._selectedItem;
			}
			set
			{
				if (value != this._selectedItem)
				{
					this._selectedItem = value;
				}
			}
		}

		~BlacklistViewModel()
		{
			if (!IsInDesignMode)
				SaveBlacklist(configFileName);
		}

		#endregion

		public bool check(String item, BlackListItemType type)
		{
			foreach(BlackListItem i in _items)
			{
				switch(type)
				{
					case BlackListItemType.Keyword:
						if (item.Contains(i.Object))
							return true;
						break;
					case BlackListItemType.PlaylistItem:
						if (item.Contains(i.Object))
							return true;
						break;
					case BlackListItemType.User:
						if (item.Contains(i.Object))
							return true;
						break;
					default:
						throw new NotImplementedException();
				}
			}
			return false;
		}

		public void LoadBlacklist(String configFileName)
		{

			if (File.Exists(Settings.Instance.configFilePath + "\\" + configFileName))
			{
				XmlSerializer deserializer = new XmlSerializer(typeof(ThreadSafeObservableCollection<BlackListItem>));
				TextReader textReader = new StreamReader(Settings.Instance.configFilePath + "\\" + configFileName);
				ThreadSafeObservableCollection<BlackListItem> _object = (ThreadSafeObservableCollection<BlackListItem>)deserializer.Deserialize(textReader);
				textReader.Close();
				if (_object == null)
				{
					_object = new ThreadSafeObservableCollection<BlackListItem>();
				}
				_items = _object;
			}
		}

		private void SaveBlacklist(String configFileName)
		{
			if (_items.Count > 0)
			{
				XmlSerializer s = new XmlSerializer(typeof(ObservableCollection<BlackListItem>));
				TextWriter writer = new StreamWriter(Settings.Instance.configFilePath + "\\" + configFileName);
				s.Serialize(writer, _items);
				writer.Close();
			}
		}

		public bool add(String Name, BlackListItemType type)
		{
			foreach (BlackListItem _item in _items)
				if (_item.Object == Name && _item.Type == type)
					return false;
			Items.Add(new BlackListItem { Object = Name, Added = DateTime.Now, Type = type });
			return true;
		}

		public bool remove(String Name)
		{
			foreach (BlackListItem _item in _items)
				if (_item.Object == Name)
				{
					Items.Remove(_item);
					return true;
				}
			return false;
		}

		#region Clear Blacklist
		void ClearExecute()
		{
			if (_items == null)
				return;

			this._selectedItem = -1;
			_items.Clear();
		}

		bool CanClearExecute()
		{
			return true;
		}

		public ICommand ClearItems { get { return new RelayCommand(ClearExecute, CanClearExecute); } }
		#endregion

		#region RemoveItem
		void RemoveBlacklistNameExecute()
		{
			if (_items == null)
				return;
			if (_selectedItem > -1)
				if (_selectedItem <= (_items.Count - 1))
					_items.Remove(_items[_selectedItem]);
		}

		bool CanRemoveBlacklistNameExecute()
		{
			return true;
		}

		public ICommand RemoveItem { get { return new RelayCommand(RemoveBlacklistNameExecute, CanRemoveBlacklistNameExecute); } }
		#endregion
	}
}
